import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core';
import { DatePipe } from '@angular/common';
import { Http } from '@angular/http';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
import { List } from 'linqts';
import { MdDatepickerModule } from '@angular/material';
import { seriesData } from './echarts.model'
import { TagData } from '../../../entity/tag-data.model';
import { DataSourceService } from '../../../service/data-source/data-source.service';
import { Tag } from '../../../entity/tag.model';
import { EchartsComponent } from '../../common/echarts/echarts.component';
import { ApplicationService } from '../../../service/application.service';
import { FarmCategoryEnum } from '../../common/device-tag-selector/farm-category.enum';
import { DeviceCategoryEnum } from '../../common/device-tag-selector/device-category.enum';
import { Device } from '../../../entity/device.model';
import { NzMessageService } from 'ng-zorro-antd';
import { InterceptorService } from '../../../service/interceptor/interceptor-service';

@Component({
  selector: 'app-turbine-trend',
  templateUrl: './turbine-trend.component.html',
  styleUrls: ['./turbine-trend.component.css'],
})
export class TurbineTrendComponent implements OnInit, OnDestroy {
  public xAxisType = 'time';
  public farmCategory: FarmCategoryEnum = FarmCategoryEnum.winfarm;
  public deviceCategories: DeviceCategoryEnum[] = [DeviceCategoryEnum.turbine];
  date: Date = new Date(new Date().getTime() - 1000 * 60 * 60 * 2);
  date2: Date = new Date();
  /**
    * 数据源服务
    * 
    * @private
    * @type {DataSourceService}
    * @memberof TurbineListComponent
    */
  private dataSource: DataSourceService;


  /**
    * 风机对象集合
    * 
    * @type {limitedTurbine[]}@memberof TurbineTrendComponent
    */
  devices: Device[];
  /**
    * 测点对象集合
    * 
    * @type {Tag[]}@memberof TurbineTrendComponent
    */
  tags: Tag[];
  /**
    * 定时器
    * 
    * @type {any}@memberof TurbineTrendComponent
    */
  private timer: any;
  /**
   * 当前选中下标
   * 
   * @type {number}@memberof TurbineTrendComponent
   */
  active: number = 0;


  /**
* echart tooltip实时数据
* 
* @type {object}@memberof TurbineTrendComponent
*/
  tooltip: {};
  /**
* 
* 
* @type {TagData[]}@memberof TurbineTrendComponent
*/
  tagDatas: TagData[] = [];
  seriesData: EchartSeriesData[];
  data: DeviceData[] = [];
  maxData: number[] = [];
  formGroup: any;
  legendData: string[] = []
  /**
* 测点
* 
* @type {any[]}@memberof TurbineTrendComponent
*/
  codeTags: string[] = ['WindSpeed', 'ActivePower'];
  /**
* 单位集合
* 
* @type {string[]}@memberof TurbineTrendComponent
*/
  uint: string[] = [];
  codes: string[] = [];
  historyTooltip: Object;
  historyMaxData: number[] = [];
  historySeries: EchartSeriesData[];
  maxDate: Date;
  minDate: Date;
  grid: object = {
    left: '64px',
    right: '64px',
    top: '10px',
    bottom: '15%',
    containLabel: true
  };
  pointcount: number = 100;
  /**
   *设备选择最大数量
   *
   * @type {number}
   * @memberof TurbineTrendComponent
   */
  deviceCountLimit = 5;
  /**
   *日期格式化
   *
   * @type {*}
   * @memberof TurbineTrendComponent
   */
  en: any;
  limitDate = 15;
  constructor(
    private fb: FormBuilder,
    private http: InterceptorService,
    private application: ApplicationService,
    private datePipe: DatePipe,
    private _message: NzMessageService) { }

  public ngOnInit() {
    this.en = {
      firstDayOfWeek: 0,
      dayNames: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
      dayNamesShort: ['日', '一', '二', '三', '四', '五', '六'],
      dayNamesMin: ['日', '一', '二', '三', '四', '五', '六'],
      monthNames: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
      monthNamesShort: ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'],
      today: '今天',
      clear: '清除'
    };
    if (this.application.currentMenuParams && this.application.currentMenuParams['pointcount']) {
      this.pointcount = parseInt(this.application.currentMenuParams.pointcount.paramValue);
    }
    if (this.application.currentMenuParams && this.application.currentMenuParams['deviceCountLimit']) {
      this.deviceCountLimit = Number(this.application.currentMenuParams['deviceCountLimit'].paramValue);
    } else {
      this.deviceCountLimit = 5;
    }
    if (this.application.currentMenuParams && this.application.currentMenuParams['limitDate']) {
      this.limitDate = Number(this.application.currentMenuParams['limitDate'].paramValue);
    }
    this.initData();
  }
  public ngOnDestroy(): void {
    if (this.dataSource != null)
      this.dataSource.dispose();
  }
  initData() {
    this.date = new Date(new Date().getTime() - 1000 * 60 * 60 * 2);
    this.date2 = new Date();
    this.formGroup = new FormGroup({
      intervalTime: new FormControl(5),
      intervalType: new FormControl('m'),
    });
    this.formGroup.controls['intervalTime']
      .valueChanges
      .debounceTime(200)
      .distinctUntilChanged()
      .subscribe((form: any) => {
        if (!form) {
          this.formGroup.controls['intervalTime'].setValue('00')
          return false;
        };
        if (form > 60 || form <= 0) {
          this.formGroup.controls['intervalTime'].setValue(5)
        }
        this.setFormValue('intervalTime', form)
      });

  }
  public onClickHeader(n: number) {
    this.active = n;
  }
  setFormValue(o: string, form: any) {
    if (form.length == 1) {
      this.formGroup.controls[o].setValue('0' + form);
    }
    this.formGroup.controls[o].setValue(parseInt(form))
  }
  /**
*获取list列表
* 
* @type {limitedTag[]}@memberof TurbineDataListComponent
*/
  getData() {
    this.data = [];
    this.tagDatas = [];
    this.uint = [];
    this.codes = [];
    this.tooltip = null;
    this.seriesData = [];
    this.historySeries = []
    //创建数据源
    if (this.dataSource != null) {
      this.dataSource.dispose();
      this.dataSource = null;
    }
    this.dataSource = new DataSourceService(this.http, this.datePipe);

    /* let groups = new List(this.turbines).GroupBy(g => g.farmCode, m => m);
    let farmCodes = Object.getOwnPropertyNames(groups); */
    let legendData = [];
    this.devices.forEach(devices => {
      this.tags.forEach((tag: Tag, tagIndex: number) => {
        this.uint.push(tag.tagUnit);
        //绑定数据
        let tagData = this.dataSource.binding([devices.farmCode, devices.deviceCode], tag);
        tagData.tagName = devices.farmName + ' ' + devices.deviceName + ' ' + tag.tagName;
        this.tagDatas.push(tagData);
        legendData.push(devices.farmName + ' ' + devices.deviceName + ' ' + tag.tagName);
        this.data.push({
          code: tagData.code,
          name: tagData.tagName,
          data: [],
        });
      });
    });
    this.legendData = legendData;
    this.tooltip = {
      trigger: 'axis',
      formatter: (params) => {
        let res = '';
        for (let i = 0; i < params.length; i++) {
          let index = params[i].seriesIndex;
          res += params[i].marker + params[i].seriesName + ':' + (params[i].value[1] ? ((params[i].value[1]) / 0.9 * (this.maxData[i])).toFixed(2) : '&nbsp;&nbsp;&nbsp;&nbsp;') + (this.uint[params[i].seriesIndex] ? '(' + this.uint[params[i].seriesIndex] + ')' : '') + '&nbsp;&nbsp;' + this.datePipe.transform((params[i].data[0]), 'HH:mm:ss') + '<br/>'
        };
        return res;
      },
    };
    this.historyTooltip = {
      trigger: 'axis',
      formatter: (params) => {
        let res = ''
        for (let i = 0; i < params.length; i++) {
          let index = params[i].seriesIndex;
          res += params[i].marker + params[i].seriesName + ':' + (params[i].value[1] ? ((params[i].value[1]) / 0.9 * (this.historyMaxData[i])).toFixed(2) : '&nbsp;&nbsp;&nbsp;&nbsp;') + (this.uint[params[i].seriesIndex] ? '(' + this.uint[params[i].seriesIndex] + ')' : '') + '&nbsp;&nbsp;' + this.datePipe.transform((params[i].data[0]), 'yy-MM-dd HH:mm:ss') + '<br/>'
        };
        return res;
      },
    };
    this.tagDatas.forEach((value: TagData, index: number) => {
      this.codes.push(value.code);
    });
    this.getHistoryData();
    this.onClickSub();
  }
  getHistoryData() {
    let date = new Date();
    this.dataSource.history
      .getHistories(this.codes, new Date(date.getTime() - 1000 * 60 * 60), date, 60 * 5)
      .then(next => {
        this.data.forEach(data => {
          const codeDatas = next.filter(o => o.code === data.code);
          codeDatas.forEach(codeData => {
            data.data.push([new Date(codeData.time), codeData.value]);
          });
        });
        /*  next.forEach(tagData => {
           let index = this.tagDatas.findIndex(o => o.code === tagData.code);
           if (index > -1) {
             this.data[index].push([new Date(tagData.time), tagData.value]);
           }
         }); */
        this.getSeries();

        this.dataSource.begin()
          .subscribe(
            next => {
              this.initEchartRealTime();
            },
            error => { });
      })
      .catch(err => {
        if (this.application.appConfigData.isShowErr) {
          this._message.info('测点数据' + err, { nzDuration: 3000 });
        }

      });
  }
  getSeries() {
    this.maxData = [];
    const seriesData: EchartSeriesData[] = [];

    this.data.forEach((value, index: number) => {
      const arr: number[] = [];
      value.data.forEach(v => {
        arr.push(v[1]);
      });
      if (!arr || !arr.length) {
        const max = 0;
        this.maxData[index] = max;
        return false;
      };
      const max: number = Math.max.apply(Math, arr);
      this.maxData[index] = max;
      const formatNumber: any[][] = [];
      this.data[index].data.forEach((v, i) => {
        formatNumber[i] = [v[0], (v[1] / max * 0.9)];
      });
      seriesData.push({
        name: value.name,
        data: formatNumber,
      });
    });
    this.seriesData = seriesData;
  }
  /**
* 得到选中风场风机集合
* 
* @type {Device[]}@memberof TurbineDataListComponent
*/

  onSelectedDevicesChange(ev: Device[]) {
    this.devices = ev;
    if (this.devices != null && this.tags != null)
      this.setTime();
  }
  /**
* 得到选中测点集合
* 
* @type {limitedTag[]}@memberof TurbineDataListComponent
*/
  public selectedTagsChange(ev: Tag[]) {
    this.tags = ev;
    if (this.devices != null)
      this.setTime();
  }

  /**
* 延迟300毫秒
* 
* @type {}@memberof TurbineDataListComponent
*/
  setTime() {
    clearTimeout(this.timer)
    this.timer = setTimeout(() => {
      this.getData()
    }, 300)
  }
  initEchartRealTime() {
    if (this.data[0] && this.data[0].data.length >= this.pointcount) {

      this.data.forEach((v, i) => {
        this.data[i].data = this.data[i].data.slice(-20);
      });

    }
    this.tagDatas.forEach((value: TagData) => {
      const index = this.data.findIndex(o => o.code === value.code);
      if (index >= 0) {
        this.data[index].data.push([new Date(value.time), value.value]);
      }

    });
    this.getSeries();
  }
  public onClickSub() {
    let myForm = this.formGroup.value;

    let interval: number;
    if (myForm.intervalType == 'h') {
      interval = myForm.intervalTime * 60 * 60;
    } else if (myForm.intervalType == 'm') {
      interval = myForm.intervalTime * 60;
    }
    if (this.date2 > new Date()) {
      alert('结束时间不能大于当前时间');
      return false;
    }
    if (this.date > this.date2) {
      alert('起始时间不能大于结束时间');
      return false;
    }
    if ((this.date2.getTime() - this.date.getTime()) > 1000 * 60 * 60 * 24 * this.limitDate) {
      alert(`最多能选择${this.limitDate}天的数据`);
      return false;
    }
    let tagCodes: string[] = [];
    let data: DeviceData[] = [];
    this.tagDatas.forEach((v, i) => {
      tagCodes.push(v.code);
      data.push({
        code: v.code,
        name: v.tagName,
        data: [],
      });
    });
    this.historyMaxData = [];
    this.dataSource.history
      .getHistories(tagCodes, this.date, this.date2, interval)
      .then(res => {
        data.forEach(d => {
          const codeDatas = res.filter(o => o.code === d.code);
          codeDatas.forEach(codeData => {
            d.data.push([new Date(codeData.time), codeData.value]);
          });
        });
        let seriesData: EchartSeriesData[] = [];
        data.forEach((value, index: number) => {
          let arr: number[] = [];
          value.data.forEach(v => {
            arr.push(v[1]);
          });
          const max: number = Math.max.apply(Math, arr);
          this.historyMaxData[index] = max;
          const formatNumber: any[][] = [];
          value.data.forEach((v, i) => {
            formatNumber[i] = [v[0], v[1] / max * 0.9];
          });
          seriesData.push({
            name: value.name,
            data: formatNumber,
          });
        });
        this.historySeries = seriesData;
      })
      .catch(err => {
        if (this.application.appConfigData.isShowErr) {
          this._message.info('历史测点数据' + err, { nzDuration: 3000 });
        }

        //console.log(err)
      })
    return false;
  }
}

interface DeviceData {
  code: string;
  name: string;
  data: [Date, number][];
}
export interface EchartSeriesData {
  name: string,
  data: any[][],
}


// WEBPACK FOOTER //
// ./src/app/module/monitor/turbine-trend/turbine-trend.component.ts